﻿using System;
using System.IO.IsolatedStorage;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using Caliburn.Micro;
using Coding4Fun.Phone.Controls;
using RemoteControl.Localization;
using VirtualKeyboard.Contract;
using VirtualKeyboard.Controls;

namespace RemoteControl.ViewModels
{
    public class MainPageViewModel : Screen, IHandle<ToastMessage>
    {
        private readonly INavigationService navigationService;
        private readonly IEventAggregator events;
        private readonly Client client;
        private IPEndPoint endPoint;
        private const string TapAction = "Tap";

        #region Commands

        public ICommand TogglePlayPauseCommand { get; private set; }
        public ICommand IncreaseVolumeCommand { get; private set; }
        public ICommand DecreaseVolumeCommand { get; private set; }
        public ICommand MuteVolumeCommand { get; private set; }
        public ICommand PreviousTrackCommand { get; private set; }
        public ICommand NextTrackCommand { get; private set; }
        public ICommand StopCommand { get; private set; }
        public ICommand FullScreenCommand { get; private set; }
        public ICommand OkCommand { get; private set; }

        #endregion

        public MainPageViewModel(INavigationService navigationService, IEventAggregator events)
        {
            this.navigationService = navigationService;
            this.events = events;
            this.events.Subscribe(this);

            client = new Client();
            client.SendCommandCompleted += OnClientSendCommandCompleted;

            TogglePlayPauseCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.TogglePlayPause));
            IncreaseVolumeCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.IncreaseVolume));
            DecreaseVolumeCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.DecreaseVolume));
            MuteVolumeCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.MuteVolume));
            PreviousTrackCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.PreviousTrack));
            NextTrackCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.NextTrack));
            StopCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.Stop));
            FullScreenCommand = new InvokeCommand(() => TapKey(KeyMethods.Media.FullScreen));

            OkCommand = new InvokeCommand(() => TapKey(KeyMethods.Keyboard.Enter));
        }

        protected override void OnViewLoaded(object view)
        {
            base.OnViewLoaded(view);
            if (!UpdateIPEndPoint())
            {
                var result = MessageBox.Show(AppResources.Please_set_the_IP_of_the_receiver);
                if (result == MessageBoxResult.OK) GoToConfig();
                return;
            }
            CheckNetwork();
        }

        protected override void OnActivate()
        {
            if (!UpdateIPEndPoint())
            {
                ShowToast(AppResources.Please_set_the_IP_of_the_receiver, AppResources.Warnring);
                return;
            }
            CheckNetwork();
        }

        private void CheckNetwork()
        {
            if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
            {
                ShowToast(AppResources.Network_is_not_available, AppResources.Warnring);
            }
        }

        private void ShowToast(string message, string title = "")
        {
            var toast = new ToastPrompt
            {
                Title = title,
                Message = message,
                TextOrientation = Orientation.Horizontal
            };
            toast.Show();
        }

        public void GoToConfig()
        {
            navigationService.UriFor<ConfigViewModel>().Navigate();
        }

        public void GoToAbout()
        {
            navigationService.UriFor<AboutViewModel>().Navigate();
        }

        public void OnLoopControlCenterClick()
        {
            if (OkCommand.CanExecute(null))
                OkCommand.Execute(null);
        }

        public void OnLoopControlLoopGlide(LoopGlideEventArg e)
        {
            int level = GetLevel(e.AngleDistance);
            if (e.Clockwise)
            {
                TapForward(level);
            }
            else
            {
                TapBackward(level);
            }
        }
        private int GetLevel(double distance)
        {
            if (distance < 45.0) return 0;
            if (distance < 90.0) return 1;
            return 2;
        }


        private bool UpdateIPEndPoint()
        {
            var ipaddress = IPEndPointStorage.IPAddress;

            if (string.IsNullOrEmpty(ipaddress)) return false;

            IPAddress ip;
            if (!IPAddress.TryParse(ipaddress, out ip)) return false;

            endPoint = new IPEndPoint(ip, IPEndPointStorage.Port);
            return true;
        }

        private void TapForward(int level)
        {
            switch (level)
            {
                default:
                    TapKey(KeyMethods.Media.Forward);
                    break;
                case 1:
                    TapKey(KeyMethods.Media.FastForward);
                    break;
                case 2:
                    TapKey(KeyMethods.Media.VeryFastForward);
                    break;
            }

        }

        private void TapBackward(int level)
        {
            switch (level)
            {
                default:
                    TapKey(KeyMethods.Media.Backward);
                    break;
                case 1:
                    TapKey(KeyMethods.Media.FastBackward);
                    break;
                case 2:
                    TapKey(KeyMethods.Media.VeryFastBackward);
                    break;
            }

        }

        private void TapKey(string keyMethod)
        {
            if (endPoint == null) return;
            client.SendCommandAsync(endPoint, TapAction, keyMethod);
        }

        private void OnClientSendCommandCompleted(object sender, SendCommandCompletedEventArgs e)
        {
            if (!e.Success)
            {
                events.Publish(new ToastMessage { Message = e.ErrMessage, Title = AppResources.Warnring });
            }
        }

        public void Handle(ToastMessage message)
        {
            ShowToast(message.Message, message.Title);
        }
    }

    public class ToastMessage
    {
        public string Title { get; set; }
        public string Message { get; set; }
    }
}
